<?php

namespace App\Http\Controllers\Pay;

use App\Http\Controllers\Controller;

use DB;
use Redirect;
use App\Model\Order;

class PingPayController extends Controller
{
	protected $keyPath;

	public function __construct()
	{
		header("Content-type:text/html;charset=utf-8");
		require_once(app_path().'/Library/PingPay/init.php');
        $this->keyPath = app_path().'/Library/PingPay/cert/';
    }

    protected function payend($info)
    {
        $data = [
            'content'=>json_encode($info),
            'addtime'=>time(),
        ];
        $re = DB::table('testorder')->insert($data);
        $result = $re ? true : false;
        return $result;
    }

	/**
	 * 获取支付渠道（类型）
	 * 此函数只返回必要的额外参数，若要非必要参数，请查阅文档：https://www.pingxx.com/api#支付渠道-extra-参数说明
	 */
	private function getExtraData($domain_url,$channel,$extra_param)
	{
		$extra = [];
		/**
		 * alipay			:	支付宝 APP 支付
		 * alipay_wap		:	支付宝手机网页支付
		 * alipay_pc_direct	:	支付宝电脑网站支付
		 * bfb_wap			:	百度钱包手机网页支付
		 * upacp_wap		:	银联全渠道手机网页支付
		 * upacp_pc			:	银联 PC 网页支付
		 * upacp			:	银联 APP 支付
		 * applepay_upacp	:	Apple Pay支付
		 * wx				:	微信支付
		 * wx_pub			:	微信公众号支付
		 * wx_pub_qr		:	微信公众号扫码支付
		 * wx_wap			:	微信 WAP 支付
		 * wx_lite			:	微信小程序支付
		 * yeepay_wap		:	易宝手机网页支付
		 * jdpay_wap		:	京东手机网页支付
		 * fqlpay_wap		:	分期乐支付
		 * qgbc_wap 		:	量化派支付
		 * cmb_wallet		:	招行一网通
		 * mmdpay_wap		:	么么贷
		 * qpay				:	QQ 钱包
		 */
		switch($channel){
			case 'alipay':
				$extra = [];
				break;
			case 'alipay_wap':
				$extra = [
					'success_url' => $domain_url.'/paysuccess',
				];
				break;
			case 'alipay_pc_direct':
				$extra = [
					'success_url' => $domain_url.'/paysuccess',
				];
				break;
			case 'bfb_wap':
				$extra = [
					'result_url' => $domain_url.'/paysuccess',
					'bfb_login' => true
				];
				break;
			case 'upacp_wap':
				$extra = [
					'result_url' => $domain_url.'/paysuccess',
				];
				break;
			case 'upacp_pc':
				$extra = [
					'result_url' => $domain_url.'/paysuccess',
				];
				break;
			case 'upacp':
				$extra = [];
				break;
			case 'applepay_upacp':
				$extra = [];
				break;
			case 'wx':
				$extra = [];
				break;
			case 'wx_wap':
				$extra = [];
				break;
			case 'wx_pub':
				$extra = [
					'open_id' => $extra_param['wx_pub_openid'],
				];
				break;
			case 'wx_lite':
				$extra = [
					'open_id' => $extra_param['wx_lite_openid'],
				];
				break;
			case 'wx_pub_qr':
				$extra = [
					'product_id' => $extra_param['wx_pub_qr_productid'],   //商品 ID，1-32 位字符串。此 id 为二维码中包含的商品 ID，商户自行维护。
				];
				break;
			case 'yeepay_wap':
				$extra = [
					'product_category' => $extra_param['yeepay_product_category'],// 商品类别码参考链接 ：https://www.pingxx.com/api#api-appendix-2
					'identity_id'=> $extra_param['yeepay_identity_id'],// 商户生成的用户账号唯一标识，最长 50 位字符串
					'identity_type' => $extra_param['yeepay_identity_type'],// 用户标识类型参考链接：https://www.pingxx.com/api#yeepay_identity_type
					'terminal_type' => $extra_param['yeepay_terminal_type'],// 终端类型，对应取值 0:IMEI, 1:MAC, 2:UUID, 3:other
					'terminal_id'=>$extra_param['yeepay_terminal_id'],// 终端 ID
					'user_ua'=>$extra_param['yeepay_user_ua'],// 用户使用的移动终端的 UserAgent 信息
					'result_url'=> $domain_url.'/paysuccess'// 前台通知地址
				];
				break;
			case 'jdpay_wap':
				$extra = [
					'success_url' => $domain_url.'/paysuccess',
					'fail_url'=> $domain_url.'/pingpay-cancel',
				];
				break;
			case 'fqlpay_wap':
				$extra = [
					'c_merch_id' => $extra_param['fqlpay_merch_id'], //子商户编号，需要提交该订单商户的所属子商户编号。
				];
				break;
			case 'qgbc_wap':
				$extra = [
					'phone' => $extra_param['qgbc_phone'], //手机号码
				];
				break;
			case 'cmb_wallet':
				$extra = [
					'result_url' => $domain_url.'/paysuccess',
					'p_no' => $extra_param['cmb_p_no'],  //客户协议号，不超过 30 位的纯数字字符串。
					'seq' => $extra_param['cmb_seq'],  //协议开通请求流水号，不超过 20 位的纯数字字符串，请保证系统内唯一。
					'm_uid' => $extra_param['cmb_m_uid'],  //协议用户 ID，不超过 20 位的纯数字字符串。
					'mobile' => $extra_param['cmb_mobile'],  //协议手机号，11 位数字。
					'discount_amount' => $extra_param['cmb_discount_amount'],  //立减金额，支付完成的返回参数，单位为分。
				];
				break;
			case 'mmdpay_wap':
				$extra = [
					'phone' => $extra_param['mmdpay_phone'],  //手机号码
					'id_no' => $extra_param['mmdpay_id_no'],  //身份证号码
					'name' => $extra_param['mmdpay_name'],  //真实姓名
				];
				break;
			case 'qpay':
				$extra = [
					'device' => $extra_param['qpay_device'],  //客户端设备类型，取值范围: "ios" ，"android"
				];
				break;
		}
		return $extra;
	}
	
	/**
	 * 发起支付
	 */
	public function payapi($payinfo)
	{
		$payset = DB::table('systemset_payinfo')->first();
		$domain_url = $payset->domain_url;
		$extra_param = $payset->ping_param ? json_decode($payset->ping_param,true) : [];

        //以下额外参数根据订单传递的值而改变，即非可直接系统设置的值
        $extra_param['wx_pub_qr_productid'] = isset($payinfo['wx_pub_qr_productid']) ? $payinfo['wx_pub_qr_productid'] : '';
        $extra_param['qpay_device'] = isset($payinfo['qpay_device']) ? $payinfo['qpay_device'] : '';

		try {
			\Pingpp\Pingpp::setApiKey($payset->ping_appkey);
            \Pingpp\Pingpp::setPrivateKeyPath($this->keyPath.'myping_rsa_private_key.pem');
			
			$ch = \Pingpp\Charge::create(
				[
					'subject'   => $payinfo['subject'],
					'body'      => $payinfo['body'],
					'amount'    => $payinfo['amount'],
					'order_no'  => $payinfo['order_no'],
					'currency'  => 'cny',
					'extra'     => $this->getExtraData($domain_url,$payinfo['channel'],$extra_param),
					'channel'   => $payinfo['channel'],
					'client_ip' => \Request::getClientIp(),
					'app'       => array('id' => $payset->ping_appid),
				]
			);
			return $ch;
		} catch (\Pingpp\Error\Base $e) {
			// 捕获报错信息
			if ($e->getHttpStatus() != null) {
				header('Status: ' . $e->getHttpStatus());
				echo $e->getHttpBody();
			} else {
				echo $e->getMessage();
			}
		}
	}

	public function notify()
    {
        $rawData = file_get_contents('php://input');
        $result = $this->verifyPing($rawData);
        if($result === 1){
            $dataInfo = json_decode($rawData,true);
            if($dataInfo['type']=='charge.succeeded'){
                $re = $this->payend($dataInfo['data']['object']);
                $re && http_response_code(200);
            }
        }else{
            $this->verifyPingFail($result);
        }
    }

    protected function verifyPing($rawData)
    {
        $headers = \Pingpp\Util\Util::getRequestHeaders();//这是Ping++的package提供的
        $signature = isset($headers['X-Pingplusplus-Signature']) ? $headers['X-Pingplusplus-Signature'] : NULL;
        $publicKeyContents = file_get_contents($this->keyPath.'ping_rsa_public_key.pem');
        return openssl_verify($rawData, base64_decode($signature), $publicKeyContents, 'sha256');
    }

    protected function verifyPingFail($result)
    {
        if ( $result === 0 ) {
            http_response_code(400);
            echo 'verification failed';
            exit;
        }
        http_response_code(400);
        echo 'verification error';
        exit;
    }
}